﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using kinokasse.bauteile.contracts.SaalpläneRepository;
using kinokasse.datamodel.contracts;

namespace kinokasse.saalplänerepo
{
    public sealed class SitzeLaden : ISitzeLaden
    {
        internal const string SaalpläneUnterverzeichnis = "Saalpläne";

        public void In_Laden(string saalnummer)
        {
            Trace.WriteLine(string.Format("SitzeLaden.In_Laden({0})", saalnummer));


            string file = GetSaalplanDatei(saalnummer);
            var sitze = Lade(file);
            Out_Sitze(sitze);
        }

        internal static string GetSaalplanDatei(string saalnummer)
        {
            return Path.Combine(SaalpläneUnterverzeichnis, saalnummer + ".txt");
        }

        internal static IEnumerable<Sitz> Lade(string file)
        {
            return Lade(File.ReadAllLines(file)).ToArray();
        }

        internal static IEnumerable<Sitz> Lade(IEnumerable<string> zeilen)
        {
            int x = 0;
            char reihe = 'A';
            foreach (var zeile in zeilen)
            {
                if (!IstLeereZeile(zeile))
                {
                    foreach (var sitz in LadeSitzeAusZeile(zeile, x, reihe))
                    {
                        yield return sitz;
                    }
                    ++reihe;
                }
                ++x;
            }
        }

        private static IEnumerable<Sitz> LadeSitzeAusZeile(string zeile, int x, char reihe)
        {
            var position = new Point(x, 0);
            int nummer = 1;
            foreach (var preisgruppe in zeile)
            {
                if (!IstLeererSitz(preisgruppe))
                {
                    yield return new Sitz(reihe.ToString(), nummer, position, preisgruppe.ToString());
                    ++nummer;
                }
                ++position.Y;
            }
        }

        internal static bool IstLeereZeile(string zeile)
        {
            return zeile.Trim().Length == 0;
        }

        internal static bool IstLeererSitz(char preisgruppe)
        {
            return preisgruppe == ' ';
        }

        public event Action<IEnumerable<Sitz>> Out_Sitze;
    }
}
